import * as THREE from 'three';
import { useRef, useState, useMemo } from 'react';
import { Text3D, Html, Edges } from '@react-three/drei';
import { gsap } from 'gsap';
import Flylines from '../Decoration/Flylines.jsx';
import Bird from '../Decoration/Bird.jsx';

const config = {
	color: '#9cb8e4',
	clearcoat: 0.5,
	reflectivity: 0.35,
	ior: 1.3,
};
const textConfig = {
	curveSegments: 32,
	bevelEnabled: true,
	bevelSize: 0,
	bevelThickness: 0,
	height: 0.02,
	letterSpacing: 0,
	size: 0.25,
};
const scale = 3.05;

const Top = ({ baseHeight, midHeightScale, topHeightScale, blocks, values, mapCenter }) => {
	let rankInfo = Object.keys(values.features).map((key) => `${key} ${values.features[key]}`);
	rankInfo.sort((a, b) => b.split(' ')[1] - a.split(' ')[1]);
	rankInfo = rankInfo.map((item, index) => index + 1 + '.' + item);
	let rank = {};
	rankInfo.forEach((item) => {
		rank[item.split('.')[1].split(' ')[0]] = item;
	});

	const blocksRef = useRef([]);
	const namesRef = useRef([]);

	const [makerVisible, setMakerVisible] = useState(false);
	const [makerPosition, setMakerPosition] = useState([0, 2, 0]);
	const [makerValue, setMakerValue] = useState('');
	const [lines, setLines] = useState({ children: [] });
	const [targetPosition, setTargetPosition] = useState({ x: 0, z: 0 });

	// 城市名称文本样式
	const cityNameStyle = {
		transition: 'all 0.2s',
		opacity: 1,
		color: '#ffffff',
		fontFamily: 'zaozigongfangtianliti',
		fontSize: '34px',
		userSelect: 'none',
		textShadow: '0 0 3px rgba(0,0,0,0.5)',
		whiteSpace: 'nowrap',
		transform: 'rotate(180deg) rotateY(180deg) rotateX(180deg)'
	};

	// 创建文本纹理函数
	const createTextTexture = (text) => {
		const canvas = document.createElement('canvas');
		const context = canvas.getContext('2d');
		canvas.width = 256;
		canvas.height = 64;
		
		context.fillStyle = 'rgba(0, 0, 0, 0)';
		context.fillRect(0, 0, canvas.width, canvas.height);
		
		context.font = '24px zaozigongfangtianliti, Arial';
		context.textAlign = 'center';
		context.textBaseline = 'middle';
		context.fillStyle = '#ffffff';
		context.fillText(text, canvas.width / 2, canvas.height / 2);
		
		const texture = new THREE.CanvasTexture(canvas);
		texture.needsUpdate = true;
		return texture;
	};
	
	// 使用useMemo缓存文本纹理，避免重复创建
	const textTextures = useMemo(() => {
		return blocks.map(item => {
			return {
				name: item.properties.name,
				texture: createTextTexture(item.properties.name)
			};
		});
	}, [blocks]);

	const handleClick = (e, index) => {
		e.stopPropagation();
		setLines({ children: [] });
		// 第二次点击选中的地图，让其恢复默认状态
		if (blocksRef.current[index].scale.z == 0.8) handleSecondClick(index);
		else {
			handleFirstClick(index);
		}
	};
	const handleFirstClick = (index) => {
		let tempArr = [];
		blocks.forEach((block, i) => {
			if (i !== index) {
				const startX = (blocks[index].properties.center[0] - mapCenter[0]) * scale;
				const startZ = -(blocks[index].properties.center[1] - mapCenter[1]) * scale;
				const endX = (block.properties.center[0] - mapCenter[0]) * scale;
				const endZ = -(block.properties.center[1] - mapCenter[1]) * scale;
				tempArr.push({
					start: [startX, baseHeight * (1 + midHeightScale + topHeightScale) + 0.3, startZ],
					end: [endX, baseHeight * (1 + midHeightScale + topHeightScale) + 0.3, endZ],
					mid: [
						startX + (endX - startX) / 5,
						baseHeight * (1 + midHeightScale + topHeightScale) + 2,
						startZ + (endZ - startZ) / 5,
					],
				});
			}
		});
		setLines({ children: [...tempArr] });
		// maker
		const region = blocks[index].properties.name;
		setMakerVisible(true);
		setMakerValue(rank[region]);
		setMakerPosition([
			(blocks[index].properties.center[0] - mapCenter[0]) * scale,
			2,
			-(blocks[index].properties.center[1] - mapCenter[1]) * scale,
		]);
		// block
		blocksRef.current.forEach((block, lastIndex) => {
			if (block.scale.z === 0.8) {
				gsap.to(blocksRef.current[lastIndex].scale, {
					duration: 0.3,
					z: topHeightScale,
				});
				blocksRef.current[lastIndex].material.color = new THREE.Color('#9cb8e4');
				
				// 处理文本显示
				if (namesRef.current[lastIndex]) {
					// 检查是HTML元素还是Three.js对象
					if (namesRef.current[lastIndex].material) {
						// 如果是精灵(使用方案二)
						namesRef.current[lastIndex].material.opacity = 1;
					} else {
						// 如果是HTML元素(使用方案一)
						if (namesRef.current[lastIndex].element) {
							namesRef.current[lastIndex].element.style.opacity = 1;
						}
					}
				}
			}
		});
		gsap.to(blocksRef.current[index].scale, { duration: 0.3, z: 0.8 });
		blocksRef.current[index].material.color = new THREE.Color('#ffb47e');
		
		// 处理文本隐藏
		if (namesRef.current[index]) {
			// 检查是HTML元素还是Three.js对象
			if (namesRef.current[index].material) {
				// 如果是精灵(使用方案二)
				namesRef.current[index].material.opacity = 0;
			} else {
				// 如果是HTML元素(使用方案一)
				if (namesRef.current[index].element) {
					namesRef.current[index].element.style.opacity = 0;
				}
			}
		}
		// bird
		setTargetPosition({ ...targetPosition, x: tempArr[0].start[0], z: tempArr[0].start[2] });
	};
	const handleSecondClick = (index) => {
		setMakerVisible(false);
		setMakerValue('');
		setMakerPosition([0, 2, 0]);
		gsap.to(blocksRef.current[index].scale, {
			duration: 0.3,
			z: topHeightScale,
		});
		blocksRef.current[index].material.color = new THREE.Color('#9cb8e4');
		
		// 处理文本显示
		if (namesRef.current[index]) {
			// 检查是HTML元素还是Three.js对象
			if (namesRef.current[index].material) {
				// 如果是精灵(使用方案二)
				namesRef.current[index].material.opacity = 1;
			} else {
				// 如果是HTML元素(使用方案一)
				if (namesRef.current[index].element) {
					namesRef.current[index].element.style.opacity = 1;
				}
			}
		}
	};
	return (
		<>
			{/* 飞鸟 */}
			{/* <Bird targetPosition={targetPosition} /> */}
			{/* 飞线 */}
			{/* <Flylines lines={lines} /> */}
			{/* 点击后的城市maker */}
			{/* <Html
				style={{
					transition: 'all 0.2s',
					opacity: makerVisible ? 1 : 0,
					transform: `scale(${makerVisible ? 1 : 0.25})`,
					userSelect: 'none',
					width: '200px',
					fontFamily: 'zaozigongfangtianliti',
					color: '#242424',
				}}
				position={makerPosition}
			>
				<h3>{makerValue}</h3>
			</Html> */}
			<group rotation={[0, Math.PI * 1.1, Math.PI]} position-y={baseHeight + midHeightScale * baseHeight + 0.01}>
				{blocks.map((item, index) => (
					<group key={'city_' + index}>
						<Html
							ref={(el) => {
								namesRef.current[index] = el;
							}}
							position={[
								(item.properties.centroid[0] - mapCenter[0]) * scale,
								-0.5,
								(item.properties.centroid[1] - mapCenter[1]) * scale,
							]}
							center
							distanceFactor={10}
							pointerEvents="none"
							occlude={false}
							style={cityNameStyle}
						>
							<div>{item.properties.name}</div>
						</Html>
					</group>
				))}
			</group>
			{/* 城市block */}
			<group
				rotation={[-Math.PI * 0.5, 0, Math.PI * 0.09]}
				position-y={baseHeight + midHeightScale * baseHeight + 0.01}
			>
				{blocks.map((item, index) => (
					<group key={'top_' + index}>
						<mesh
							scale={[1, 1, topHeightScale]}
							geometry={blocks[index].children[0].geometry}
							ref={(el) => {
								blocksRef.current[index] = el;
							}}
							onClick={(e) => handleClick(e, index)}
						>
							<meshPhysicalMaterial
								{...config}
								transmission={Math.sqrt(
									item.properties.value / Math.max(...Object.values(values.features))
								)}
								roughness={Math.sqrt(
									item.properties.value / Math.max(...Object.values(values.features))
								)}
							/>
							<Edges color={'#ffffff'} />
						</mesh>
					</group>
				))}
			</group>
		</>
	);
};

export default Top;
